home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / N-P / PixelFlipper src / Sources / PixelFlipperINIT.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-07  |  12.2 KB  |  346 lines  |  [TEXT/KAHL]

  1. /*
  2.     PixelFlipperINIT.c
  3.     written in Think C 4.0 by Chris Sanchez
  4.     Copyright ©1990 Chris Sanchez, All Rights Reserved
  5. */
  6.  
  7. #include     "PixelFlipper.h"
  8.  
  9. /*                Global Variables            */
  10. long            gOldGNETrap, gOldWNETrap;
  11. GDHandle     gCurGDev;            /* This is the current graphics device            */
  12. PREFRec        gPrefs;                /* This is the preferences for the INIT            */
  13. short            gTempPerm;        /* for the menu hook                                                 */
  14. Str255        gBitStr, gCursStr, gMenuStr;
  15.  
  16. /*                    Prototypes                */
  17. pascal char NewGNETrap( short theMask, EventRecord *theEvent );
  18. pascal char NewWNETrap( short theMask, EventRecord *theEvent, unsigned long sleep, RgnHandle mouseRgn );
  19. void main(void);
  20. /**********************************************************************************************
  21.                                                     Private Routines for PixelFlipper
  22. **********************************************************************************************/
  23. static pascal short HasDepth( GDHandle gd, short newDepth, short whichFlags, short newFlags )
  24.     = {0x203C, 0x000A, 0x0014, 0xAAA2};
  25.  
  26. static pascal short SetDepth( GDHandle gd, short newDepth,short whichFlags, short newFlags )
  27.     = {0x203C, 0x000A, 0x0013, 0xAAA2};
  28.  
  29. static Boolean keyIsDown(unsigned int k)
  30. /*    ->    k is a key code to check if being pressed.
  31.         <-    returns TRUE if the key is down.
  32. */
  33. {    unsigned char    km[16];
  34.     
  35.     GetKeys(km);
  36.     return((km[k>>3] >> (k & 7)) & 1);
  37. }
  38.  
  39. static GDHandle FindGDev()
  40. /*    ->    void. Takes no parameters.
  41.         <-    GDHandle. The handle to the graphics device that the mouse was down in.
  42. */
  43. {    Point            theMouse;
  44.     GDHandle    gdevs;
  45.  
  46.     GetMouse(&theMouse);
  47.     for(gdevs = GetDeviceList();gdevs;gdevs = GetNextDevice(gdevs))
  48.         if (TestDeviceAttribute(gdevs, screenDevice) && TestDeviceAttribute(gdevs, screenActive) && PtInRect(theMouse, &(**gdevs).gdRect))
  49.             return gdevs;
  50.     return GetGDevice();    /* just return the current device */
  51. }    
  52.  
  53. static GetColors( Boolean *mode, short *bits )
  54. /*    ->    mode, bits. The mode is the screen setting (0 = B&W, 1 = Color )
  55.                     bits is the pixel depth of the selected GDevice.
  56.         <-    returns nothing.
  57. */
  58. {    
  59.     gCurGDev = FindGDev();            /* always update the graphics device global */
  60.     *mode = ((**gCurGDev).gdFlags & 1);
  61.     *bits    =(**(**gCurGDev).gdPMap).pixelSize;
  62. }
  63.  
  64. static MakePerm(short theDepth, short theMode)
  65. /*    ->    theDepth, theMode. The theDepth and mode are the settings that the user
  66.                 has requested to be changed.  These changes are made in the 'scrn' = 0 resource
  67.                 in the system file.
  68.         <-    returns nothing.
  69. */
  70. {    short            **screens, *scrn;
  71.     short            numCtl, numDevs, i, j, oldRef;
  72.     Rect            theRect, diffRect;
  73.     
  74.     #define    kOffSetToRect 9
  75.     #define    kOffSetToMode    4
  76.     #define    kOffSetToFlag    6
  77.     #define    kOffSetToCtl    13
  78.  
  79.     oldRef = CurResFile();
  80.     UseResFile(0);        /*use the system file */
  81.     theRect = (**gCurGDev).gdRect;    /*    the rect of the graphics devide we are in */
  82.     if (!TestDeviceAttribute(GetDeviceList(), allInit)) return;     /*  were devices initalized from 'scrn 0' resource    */
  83.     if ((screens = Get1Resource('scrn', 0)) == NIL) return;            /* can't find the scrn 0 resource                */
  84.     numDevs = **screens;
  85.     scrn = *screens;    /*    Get a pointer if ints */
  86.     scrn += 1;    /* scrn now points to the beginning of the data */
  87.     for (i=0;i < numDevs;i++){
  88.         if (SectRect(&theRect,scrn + kOffSetToRect, &diffRect)){
  89.             *(scrn + kOffSetToMode) = (**gCurGDev).gdMode;
  90.             if (*(scrn + kOffSetToFlag) & 1){
  91.                 if (!theMode)
  92.                     *(scrn + kOffSetToFlag) ^= 1;
  93.             }else
  94.                 if (theMode)
  95.                     *(scrn + kOffSetToFlag) |= 1;
  96.  
  97.             ChangedResource(screens);
  98.             UpdateResFile(0);
  99.             break;
  100.         }else{    /* goto the next one, calculate the offset to the next device record */
  101.             scrn += kOffSetToCtl;
  102.             numCtl = *scrn;
  103.             scrn +=1;    /*    now to the beginning of the control data. */
  104.             for (j = 0; j < numCtl; j++){    /* step through the controls */
  105.                 scrn += 4;    /*    1 for the csCode, 1 for the length, 2 for the paramBlkPtr. */
  106.             }
  107.         }
  108.     }
  109.     ReleaseResource(screens);
  110.     UseResFile(oldRef);
  111. }
  112.  
  113. static pascal void MyMenuHook()
  114. /*    ->    nothing is passed in.  MenuHook to see if the "P" key is down.  This will make the
  115.                 change permanent.
  116.         <-    nothing is returned.
  117. */
  118. {    Cursor        handCurs;
  119.     EventRecord    e;
  120.     Boolean        r;
  121.     
  122.     SetUpA4();
  123.     if (keyIsDown(kTempPerm)){
  124.         StuffHex(&handCurs, gCursStr);
  125.         SetCursor(&handCurs);
  126.         gTempPerm = TRUE;
  127.     }else{
  128.         InitCursor();
  129.         gTempPerm = FALSE;
  130.     }
  131.     r = CallPascalB(everyEvent, &e, gOldGNETrap);
  132.     RestoreA4();
  133. }
  134.  
  135. static AddDepth(MenuHandle m, short depth, short *total, short *curBit)
  136. /*    ->    m is a handle to our popupMenu that we are adding depths to. depth is the depth we wish
  137.                 to add to the menu. total is total number of depth items added to the menu thus far.
  138.                 curBit is the item number in the menu of the current bit for this gDevice.
  139.         <-    nothing is returned.
  140. */
  141. {    Str255        theStr;
  142.  
  143.     if (HasDepth(gCurGDev, depth, kFlagCnt, kColor) || HasDepth(gCurGDev, depth, kFlagCnt, kBW)){    /* Does the monitor have this depth in color or b&w */
  144.         NumToString((long)depth, theStr);    /*     yes, then convert the number to a string.    */
  145.         pStrcat(theStr, gBitStr);    /*     append the word Bit to the item    */
  146.         AppendMenu(m, theStr);        /*    add it to the menu                            */
  147.         *total += 1;                            /*     increment the counter                        */
  148.         if (*curBit == depth){        /*    is this the bit of the current setting    */
  149.             *curBit = CountMItems(m);    /* find out its' real index in the menu.    */
  150.             CheckItem(m, *curBit, 1);    /* and check the item in the menu.                */
  151.         }
  152.     }
  153. }
  154.  
  155. static DoPatch(EventRecord    *theEvt)
  156. /*    ->    theEvt.  theEvt gives us some info as to what has occured.  This porcedure will handle
  157.                 the building of the popup on the file, and will respond to the actions assoc. with that
  158.                 menus item list.
  159.         <-    returns nothing
  160. */
  161. {    short            selectedItem, currentDepth;
  162.     long            selectedDepth = 1;
  163.     MenuHandle    fMenu;
  164.     Str255        theStr;
  165.     short            itemPosition = 0, numDepths = 0, modePosition;
  166.     long            *theMenuHook;
  167.     long            saveMHook;
  168.     Handle        oldMBar;
  169.     GrafPtr        port;
  170.     char            process = FALSE, currentMode;
  171.     
  172.     GetPort(&port);
  173.     if (fMenu = NewMenu(kFlipMenuID, nullStr)){
  174.         HNoPurge(fMenu);
  175.         GetColors(¤tMode, ¤tDepth);                /* currentMode : FALSE=gray, TRUE=color; currentDepth = pixeldepth    */
  176.         itemPosition = currentDepth;
  177.         AddDepth(fMenu, 1, &numDepths, &itemPosition);    /*    Check for some depths                                                    */
  178.         AddDepth(fMenu, 2, &numDepths, &itemPosition);    /*    If you needed, then this the place where you    */
  179.         AddDepth(fMenu, 4, &numDepths, &itemPosition);    /*    would add different depths.                                        */
  180.         AddDepth(fMenu, 8, &numDepths, &itemPosition);            
  181.         AddDepth(fMenu, 15, &numDepths, &itemPosition);            
  182.         AddDepth(fMenu, 16, &numDepths, &itemPosition);            
  183.         AddDepth(fMenu, 24, &numDepths, &itemPosition);            
  184.         AddDepth(fMenu, 32, &numDepths, &itemPosition);                        
  185.         AppendMenu(fMenu, gMenuStr);                                    /*    add the Grays and Colors items to the menu        */
  186.         modePosition = (currentMode*1)+numDepths+2;
  187.         CheckItem(fMenu, modePosition, 1);                        /* relative to the menu                                                     */
  188.         if (currentDepth == 1){                                                /* if we are in b & w                                                         */
  189.             DisableItem(fMenu, numDepths+2);
  190.             DisableItem(fMenu, numDepths+3);
  191.         }
  192.         oldMBar = GetMenuBar();
  193.         InsertMenu(fMenu, kbeforeID);
  194.         if (gCursStr[0] != 0){
  195.             theMenuHook    = (long *)kMenuHook;
  196.             saveMHook = *theMenuHook;                            /* Install the menu hook to our    */        
  197.             *theMenuHook = (long)&MyMenuHook;            /* call back procedure                */
  198.         }
  199.         gTempPerm = FALSE;
  200.         if (selectedItem = LoWord(PopUpMenuSelect(fMenu, theEvt->where.v, theEvt->where.h, itemPosition))){
  201.             if ((selectedItem <= numDepths) && (selectedItem != itemPosition)){
  202.                 process = TRUE;
  203.                 itemPosition = selectedItem;
  204.             }else 
  205.                 switch (selectedItem - (numDepths+1)){
  206.                     case 1:        /* chose gray from the menu */
  207.                     case 2:        /* chose color                            */
  208.                         if (selectedItem != modePosition){
  209.                             currentMode = currentMode ? kBW : kColor;
  210.                             process = TRUE;
  211.                         }
  212.                         break;
  213.                 }
  214.  
  215.             if (process){
  216.                 GetItem (fMenu, itemPosition, theStr);
  217.                 theStr[0] -= kLeading;
  218.                 StringToNum(theStr, &selectedDepth);
  219.                 if (SetDepth(gCurGDev, (short)selectedDepth, kFlagCnt, (short)currentMode) == 0)
  220.                     if (gPrefs.isPerm || gTempPerm )
  221.                         MakePerm((short)selectedDepth ,currentMode);
  222.             }
  223.         }
  224.         InitCursor();
  225.         if (gCursStr[0] != 0)
  226.             *theMenuHook = saveMHook;
  227.         DeleteMenu(kFlipMenuID);
  228.         SetMenuBar(oldMBar);
  229.         DisposeMenu(fMenu);
  230.     }
  231.     SetPort(port);
  232. }
  233.  
  234. static void ShowInit(short theID)
  235. /*    ->    theID is the CICN or ICN# ID to show at start up. The procedure was compiled with MPW Asm
  236.                 to a 'proc' resource and called directly with CallPascal.
  237.                 ShowINITCredits:
  238.                     ShowINIT by Paul Mercer
  239.                     Copyright 1987-1988
  240.                     Version of 7/15/88
  241.         <-    returns nothing
  242. */
  243. {    Handle    theRes;
  244.  
  245.     if(theRes = Get1Resource('proc', kShowID)){
  246.         MoveHHi(theRes);
  247.         HLock(theRes);
  248.         CallPascal(theID, kbeforeID, *theRes);
  249.         HUnlock(theRes);
  250.         ReleaseResource(theRes);
  251.     }
  252. }
  253. /**********************************************************************************************/
  254. /*                                                    Public Routines for PixelFlipper                                                                    */
  255. /**********************************************************************************************/
  256. pascal char NewGNETrap(short theMask, EventRecord    *theEvent)
  257. /*    ->    theMask, theEvent are standard arguments passed to GetNextEvent().  Checks to see if 
  258.                 an event that we must respond to has occured and one of our windows is not active, if
  259.                 both these occur, then we DoPatch. 
  260.         <-    returns char which tells if an event was available.
  261. */
  262. {    char            theVal;
  263.     
  264.     SetUpA4();
  265.     theVal = CallPascalB(theMask, theEvent, gOldGNETrap);
  266.     if (gPrefs.active && (theEvent->what == mouseDown) && (theEvent->modifiers == gPrefs.hotKey)){
  267.         DoPatch(theEvent);
  268.         theVal = FALSE;        
  269.     }
  270.     RestoreA4();
  271.     return theVal;
  272. }
  273.  
  274. pascal char NewWNETrap( short theMask, EventRecord    *theEvent, unsigned long sleep, RgnHandle mouseRgn )
  275. /*    ->    theMask, theEvent, sleep, mouseRgn are standard arguments passed to WaitNextEvent().  
  276.                 Checks to see if an event that we must respond to has occured and one of our windows 
  277.                 is not active, if both these occur, then we DoPatch. 
  278.         <-    returns char which tells if an event was available.
  279. */
  280. {    char            theVal;
  281.     
  282.     SetUpA4();
  283.     theVal = CallPascalB( theMask, theEvent, sleep, mouseRgn, gOldWNETrap );
  284.     if (gPrefs.active && (theEvent->what == mouseDown) && (theEvent->modifiers == gPrefs.hotKey)){
  285.         DoPatch(theEvent);
  286.         theVal = FALSE;        
  287.     }
  288.     RestoreA4();
  289.     return theVal;
  290. }
  291.  
  292. void main()
  293. { Handle            myHandle;
  294.     Ptr                    myPtr;
  295.     SysEnvRec        myEnv;
  296.     hdrPtr            h;
  297.     short                cnt, i;
  298.     
  299.     asm{
  300.         move.l A0, myPtr                                                /*    The address of our INIT is    */
  301.     }                                                                                    /*    stored in A0 upon entry.        */
  302.     RememberA0();                                                            /*    So we can access our globals*/
  303.     SetUpA4();
  304.     myHandle = RecoverHandle(myPtr);                    /*     Get a handle to ourself and    */
  305.     DetachResource(myHandle);                                    /*     detach ourselves.                        */
  306.     SysEnvirons (curSysEnvVers,&myEnv);                /*     Get some system info.                */
  307.     ClearPointer(&gPrefs, sizeof(PREFRec));        /*     make sure the variable is cleared.*/
  308.     if (!myEnv.hasColorQD || myEnv.systemVersion < 0x0605 || keyIsDown(kBypass) || !Get_Set_Prefs(&gPrefs, myEnv.sysVRefNum, getting)){
  309.         ShowInit(kICNBad);                                            /*    We weren't able to do this, */
  310.         return;                                                                    /*    so bail out while we can!        */
  311.     }    
  312.     asm{
  313.         move.l    #sizeof (hdr),D0
  314.         _NewPtr    SYS + CLEAR
  315.         move.b    D0, MemErr
  316.         beq.s        @1
  317.         move.w    #kICNBad, -(A7)
  318.         jsr            ShowInit
  319.         return
  320. @1    move.l    A0,h                                ; address of storage
  321.     }
  322.     h->hdrVal = 0xA89F1234;                                        /*    universal header bytes so our cdev will be able to communicate    */
  323.     h->creator = kOurCreat;                                        /*    with our INIT. our creator                                                                            */
  324.     h->prefs = &gPrefs;                                                /*     make it point to global data                                                                        */
  325.     GetIndString(gBitStr, kStrPixel, kBits);
  326.     if (ResError() != noErr)
  327.         pStrcpy(gBitStr, nullStr);
  328.     GetIndString(gCursStr, kStrPixel, kCurs);
  329.     if (ResError() != noErr)
  330.         pStrcpy(gCursStr, nullStr);
  331.     GetIndString(gMenuStr, kStrPixel, kMenuStr);
  332.     if (ResError() != noErr){
  333.         ShowInit(kICNBad);
  334.         DisposPtr(h);
  335.         return;
  336.     }    
  337.     /*    Now we can patch some traps    */
  338.     gOldGNETrap = NGetTrapAddress( kGNETrap, ToolTrap );
  339.     NSetTrapAddress( NewGNETrap, kGNETrap, ToolTrap );        /* Patch GetNextEvent()        */
  340.     if ((gOldWNETrap = NGetTrapAddress( kWNETrap, ToolTrap ))!=NGetTrapAddress( kUNITrap, ToolTrap ))    /* is WaitNextEvent() implemented */
  341.         NSetTrapAddress( NewWNETrap, kWNETrap, ToolTrap );    /* Patch WaitNextEvent()    */
  342.     if (gPrefs.showIcon)
  343.         ShowInit(kICNGood);
  344.     gCurGDev = GetGDevice();
  345.     RestoreA4();
  346. }